#pragma once

#include "..\\headers.default.h"

using namespace loirey;

namespace and_or_tree
{
	class CBasicInstance
	{
	public:
		double x, y;

	public:
		virtual bool InputFromStream(istream& inStream);
		virtual void OutputToStream(ostream& outStream, bool fUseShortFormat) const;
	};

	class CParsedInstance : public CBasicInstance
	{
	public:
		static double S_MinPositionDifference;
		static double S_MinRotationDifference;
		static double S_MinScaleDifference;
	public:
		double rotation, scale;
	public:
		int Tag;
	public:
		double node_shape_score;
		double node_appearance_score;
		double node_total_score;
		double tree_shape_score;
		double tree_appearance_score;
		double tree_total_score;

	public:
		CParsedInstance();
		void ClearAll();
		void ClearScore();
	public:
		void RefreshTotalScore();
	public:
		virtual bool InputFromStream(istream& inStream);
		virtual void OutputToStream(ostream& outStream, bool fUseShortFormat) const;
	public:
		static bool AreSameByInstance(const CParsedInstance& a, const CParsedInstance& b);
	public:
		static bool CompareByTreeScore_Smaller(const CParsedInstance& a, const CParsedInstance& b);
		static bool CompareByTreeScore_Bigger(const CParsedInstance& a, const CParsedInstance& b);
	};

	class CRichInstance : public CBasicInstance
	{
	public:
		int ChildrenAmount;
		CSimpleTypeArray<double> OrientationList;
		CSimpleTypeArray<double> LengthList;

	public:
		int ComputeOffset_SingleChild(int ChildIndex) const;
		int ComputeOffset_ChildrenPair(int ChildIndexA, int ChildIndexB) const;
	public:
		CRichInstance();
		void Clear();
		void SetChildrenAmount(int ChildrenAmount);

	public:
		void InitAll(const CSimpleTypeArray<const CBasicInstance*>& ChildrenPtrList, double x, double y);
		void InitAll(const CSimpleTypeArray<const CBasicInstance*>& ChildrenPtrList);
		void Init_CC_Pairs(const CSimpleTypeArray<const CBasicInstance*>& ChildrenPtrList);
	public:
		void Compute_PC_Pairs(const CSimpleTypeArray<const CBasicInstance*>& ChildrenPtrList, double x, double y);
		void Compute_PC_Pairs(const CSimpleTypeArray<const CBasicInstance*>& ChildrenPtrList);
		void Compute_CC_Paris(const CSimpleTypeArray<const CBasicInstance*>& ChildrenPtrList);

	public:
		void InitAll(const CSimpleTypeArray<const CParsedInstance*>& ChildrenPtrList, double x, double y);
		void InitAll(const CSimpleTypeArray<const CParsedInstance*>& ChildrenPtrList);
		void Init_CC_Pairs(const CSimpleTypeArray<const CParsedInstance*>& ChildrenPtrList);
	public:
		void Compute_PC_Pairs(const CSimpleTypeArray<const CParsedInstance*>& ChildrenPtrList, double x, double y);
		void Compute_PC_Pairs(const CSimpleTypeArray<const CParsedInstance*>& ChildrenPtrList);
		void Compute_CC_Paris(const CSimpleTypeArray<const CParsedInstance*>& ChildrenPtrList);
	};

	class CInstanceChoice : public CParsedInstance
	{
	public:
		bool fIsfake;
		bool fHasFakeChildren;
	public:
		CSimpleTypeArray<int> ChildrenChoiceIndexList;
	
	public:
		CInstanceChoice();
		void ClearChildrenChoices(int ChildrenAmount = 0);
	public:
		virtual bool InputFromStream(istream& inStream);
		virtual void OutputToStream(ostream& outStream, bool fUseShortFormat) const;
	};

}

